package com.fuxinglianbao.services;

import com.fuxinglianbao.models.CyclePeriod;
import com.fuxinglianbao.models.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

@Service
public class HelpService {
    @Autowired
    private EntityManager entityManager;

    @Autowired
    private UserService userService;

    @Autowired
    private CyclePeriodService cyclePeriodService;

    @Transactional
    public void processHelpPoint(Long sourceUserId, int sourceStarLevel) {
        // 优先级1：帮扶"最近且临门一脚"者
        if (tryHelpNearCompletion(sourceUserId, sourceStarLevel)) {
            return;
        }

        // 优先级2：帮扶"最近且有进展"者
        if (tryHelpProgressMade(sourceUserId, sourceStarLevel)) {
            return;
        }

        // 优先级3：帮扶"直推下线的空位"
        if (tryHelpDirectReferrals(sourceUserId, sourceStarLevel)) {
            return;
        }

        // 最终失败处理：转为全局滑落
        handleGlobalSpillover(sourceUserId, sourceStarLevel);
    }

    private boolean tryHelpNearCompletion(Long sourceUserId, int sourceStarLevel) {
        List<CyclePeriod> nearCompletionCycles = cyclePeriodService.findNearCompletionCycles(sourceUserId, sourceStarLevel);
        
        if (nearCompletionCycles.isEmpty()) {
            return false;
        }

        // 选择最近的用户（层级最小）
        CyclePeriod targetCycle = selectNearestCycle(nearCompletionCycles);
        if (targetCycle != null) {
            placeHelpPoint(targetCycle, sourceUserId);
            return true;
        }

        return false;
    }

    private boolean tryHelpProgressMade(Long sourceUserId, int sourceStarLevel) {
        List<CyclePeriod> progressMadeCycles = cyclePeriodService.findProgressMadeCycles(sourceUserId, sourceStarLevel);
        
        if (progressMadeCycles.isEmpty()) {
            return false;
        }

        // 选择最近的用户（层级最小）
        CyclePeriod targetCycle = selectNearestCycle(progressMadeCycles);
        if (targetCycle != null) {
            placeHelpPoint(targetCycle, sourceUserId);
            return true;
        }

        return false;
    }

    private boolean tryHelpDirectReferrals(Long sourceUserId, int sourceStarLevel) {
        List<CyclePeriod> directReferralCycles = cyclePeriodService.findDirectReferralCycles(sourceUserId, sourceStarLevel);
        
        for (CyclePeriod cycle : directReferralCycles) {
            List<TreeNode> nodes = cyclePeriodService.getTreeNodes(cycle.getId());
            Optional<Integer> emptyPosition = findFirstEmptyPosition(nodes);
            
            if (emptyPosition.isPresent()) {
                User beneficiary = findBeneficiaryForPosition(cycle.getId(), emptyPosition.get());
                if (beneficiary != null && beneficiary.getStarLevel() <= sourceStarLevel) {
                    cyclePeriodService.addMember(cycle.getId(), sourceUserId, emptyPosition.get(), true, sourceUserId);
                    cyclePeriodService.markAsReceived(cycle.getId());
                    return true;
                }
            }
        }

        return false;
    }

    private void handleGlobalSpillover(Long sourceUserId, int sourceStarLevel) {
        // 从根用户开始，使用TTB-LTR算法寻找合适的位置
        User rootUser = findRootUser();
        processGlobalSpillover(rootUser.getId(), sourceUserId, sourceStarLevel);
    }

    private CyclePeriod selectNearestCycle(List<CyclePeriod> cycles) {
        return cycles.stream()
                .min(Comparator
                        .comparing((CyclePeriod c) -> calculateLevelDistance(c.getUser().getId()))
                        .thenComparing(c -> c.getUser().getStarLevelActivationTime())
                        .thenComparing(c -> c.getUser().getRegistrationTime()))
                .orElse(null);
    }

    private void placeHelpPoint(CyclePeriod cycle, Long sourceUserId) {
        List<TreeNode> nodes = cyclePeriodService.getTreeNodes(cycle.getId());
        Optional<Integer> emptyPosition = findFirstEmptyPosition(nodes);
        
        if (emptyPosition.isPresent()) {
            cyclePeriodService.addMember(cycle.getId(), sourceUserId, emptyPosition.get(), true, sourceUserId);
            cyclePeriodService.markAsReceived(cycle.getId());
        }
    }

    private Optional<Integer> findFirstEmptyPosition(List<TreeNode> nodes) {
        // 实现TTB-LTR算法查找第一个空位
        for (int i = 0; i < 7; i++) {
            final int position = i;
            if (nodes.stream().noneMatch(n -> n.getPositionIndex() == position)) {
                return Optional.of(i);
            }
        }
        return Optional.empty();
    }

    private User findBeneficiaryForPosition(Long cycleId, int position) {
        // 根据位置索引找到直接上级用户
        int parentIndex = (position - 1) / 2;
        List<TreeNode> nodes = cyclePeriodService.getTreeNodes(cycleId);
        
        return nodes.stream()
                .filter(n -> n.getPositionIndex() == parentIndex)
                .map(TreeNode::getUser)
                .findFirst()
                .orElse(null);
    }

    private int calculateLevelDistance(Long userId) {
        User user = userService.getUser(userId);
        int distance = 0;
        
        while (user.getReferrer() != null && !isRootUser(user.getReferrer().getId())) {
            distance++;
            user = user.getReferrer();
        }
        
        return distance;
    }

    private User findRootUser() {
        try {
            return entityManager.createQuery(
                "SELECT u FROM User u WHERE u.id = 1", User.class)
                .getSingleResult();
        } catch (NoResultException e) {
            throw new IllegalStateException("根用户不存在");
        }
    }

    private boolean isRootUser(Long userId) {
        return userId != null && userId == 1L;
    }

    @Transactional
    public void processUpgrade(Long userId, int newStarLevel) {
        User user = userService.getUser(userId);
        
        // 步骤1: 更新用户状态
        updateUserStatus(user, newStarLevel);

        // 步骤2: 尝试向上帮扶
        if (!tryUplineHelp(user, newStarLevel)) {
            // 如果向上帮扶失败，转为全局滑落
            handleGlobalSpillover(userId, newStarLevel);
        }
    }

    private void updateUserStatus(User user, int newStarLevel) {
        user.setStarLevel(newStarLevel);
        user.setStarLevelActivationTime(LocalDateTime.now());
        entityManager.merge(user);

        // 创建新的成团周期
        cyclePeriodService.createNewCyclePeriod(user.getId(), newStarLevel);
    }

    private boolean tryUplineHelp(User user, int starLevel) {
        // 获取用户的直接上级
        User upline = user.getReferrer();
        
        // 检查是否存在有效上级（非根用户）
        if (upline == null || isRootUser(upline.getId())) {
            return false;
        }

        // 获取上级的活跃周期
        CyclePeriod uplineCycle = cyclePeriodService.findActiveCycle(upline.getId(), starLevel);
        if (uplineCycle == null || uplineCycle.isCompleted() || uplineCycle.getHasReceivedHelp()) {
            return false;
        }

        // 在上级树中寻找合适位置
        List<TreeNode> nodes = cyclePeriodService.getTreeNodes(uplineCycle.getId());
        Optional<Integer> emptyPosition = findFirstEmptyPosition(nodes);
        
        if (emptyPosition.isPresent()) {
            User beneficiary = findBeneficiaryForPosition(uplineCycle.getId(), emptyPosition.get());
            if (beneficiary != null && beneficiary.getStarLevel() >= starLevel) {
                cyclePeriodService.addMember(uplineCycle.getId(), user.getId(), emptyPosition.get(), true, user.getId());
                cyclePeriodService.markAsReceived(uplineCycle.getId());
                return true;
            }
        }
        
        return false;
    }

    private void processGlobalSpillover(Long currentUserId, Long sourceUserId, int sourceStarLevel) {
        CyclePeriod cycle = cyclePeriodService.findActiveCycle(currentUserId, sourceStarLevel);
        if (cycle != null && !cycle.isCompleted() && !cycle.getHasReceivedHelp()) {
            List<TreeNode> nodes = cyclePeriodService.getTreeNodes(cycle.getId());
            Optional<Integer> emptyPosition = findFirstEmptyPosition(nodes);
            
            if (emptyPosition.isPresent()) {
                User beneficiary = findBeneficiaryForPosition(cycle.getId(), emptyPosition.get());
                if (beneficiary != null && beneficiary.getStarLevel() <= sourceStarLevel) {
                    cyclePeriodService.addMember(cycle.getId(), sourceUserId, emptyPosition.get(), true, sourceUserId);
                    cyclePeriodService.markAsReceived(cycle.getId());
                    return;
                }
            }
        }

        // 继续处理下级用户
        List<User> directReferrals = findDirectReferrals(currentUserId);
        for (User referral : directReferrals) {
            processGlobalSpillover(referral.getId(), sourceUserId, sourceStarLevel);
        }
    }

    private List<User> findDirectReferrals(Long userId) {
        return entityManager.createQuery(
                "SELECT u FROM User u WHERE u.referrer.id = :userId", User.class)
                .setParameter("userId", userId)
                .getResultList();
    }
}